package com.fingard.dsp.bank.directbank.bfb01;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fingard.constant.Format;
import com.fingard.crypto.SignVerifyHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.SortHelper;
import com.fingard.util.TransIDHelper;

public class BFB01Base extends DirectBase {
	private static TransIDHelper idHelper = new TransIDHelper(1, 99999);
	
	protected String getQryTransID() {
		Date tmpDateNow = new Date();
		return Format.DateTime12Year2Format.format(tmpDateNow) + idHelper.getNextIDStr();
	}
	
	protected String getCharset() {
		return getBankConfig().getCharset("GBK");
	}
	
	protected String convertMoney(String str) {
		int money = Integer.parseInt(str);
		String backMoney = String.valueOf(money);
		
		return backMoney;
	}
	
	public static byte[] hexStringToBytes(String hexString) {   
	    if (hexString == null || hexString.equals("")) {   
	        return null;   
	    }   
	    hexString = hexString.toUpperCase();   
	    int length = hexString.length() / 2;   
	    char[] hexChars = hexString.toCharArray();   
	    byte[] d = new byte[length];   
	    for (int i = 0; i < length; i++) {   
	        int pos = i * 2;   
	        d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));   
	    }   
	    return d;   
	}   
	
	 protected static byte charToByte(char c) {   
	    return (byte) "0123456789ABCDEF".indexOf(c);   
	}  
	 
	/**
	 * 获取公钥
	 * 
	 * @param actItem
	 * @return
	 * @throws Exception
	 */
	protected PublicKey getPublicKey(String publicKeyStr) throws Exception {
		 byte[] keyBytes = hexStringToBytes(publicKeyStr); 
		 
		 /*File file = new File("d:\\Test.cer");
		//建立输出字节流
		FileOutputStream fos = new FileOutputStream(file);
		//用FileOutputStream 的write方法写入字节数组
		fos.write(keyBytes);
		//为了节省IO流的开销，需要关闭
		fos.close();*/
         
 		InputStream is = new ByteArrayInputStream(keyBytes);
        CertificateFactory cf = CertificateFactory.getInstance("x509");   
        Certificate cerCert = cf.generateCertificate(is);
        PublicKey tmpPublicKey = cerCert.getPublicKey();
         
         return tmpPublicKey; 
	}

	/**
	 * 获取HTTP发送数据
	 * 
	 * @param map
	 * @param actItem
	 * @return
	 * @throws Exception
	 */
	protected String getHttpPostStr(HashMap<String, String> p_reqmap, ActSetItem actItem) throws Exception {
		String signStr = getSignStr(p_reqmap);

		WriteBankLogLn2("签名原始串为: " + signStr);

		// 获取商户证书
		StringBuilder tmpSb = new StringBuilder();
		byte[] tmpPublicKey = SignVerifyHelper.getBytePublicKey("PKCS12", actItem.ownKeyStorePath,
				actItem.ownKeyPassword, tmpSb);
		
		String merchantCert = StringHelper.bytesToHexString(tmpPublicKey);

		// 获取商户签名
		StringBuilder sbLog = new StringBuilder();
		byte[] signature = SignVerifyHelper.signData(signStr.getBytes(getCharset()), "PKCS12", "SHA1withRSA",
				actItem.ownKeyStorePath, actItem.ownKeyPassword, sbLog);
		
		String merchantSign = StringHelper.bytesToHexString(signature);

		// 获取HTTP请求数据
		String sendStr = "";
		for (String key : p_reqmap.keySet()) {
			sendStr += "&" + key + "=" + URLEncoder.encode(p_reqmap.get(key), getCharset());
		}
		sendStr += "&merchantSign=" + merchantSign.toUpperCase() + "&merchantCert=" + merchantCert.toUpperCase();
		sendStr = sendStr.substring(1);

		return sendStr;
	}

	/**
	 * 发送邦付宝(快捷支付)
	 * 
	 * @param p_reqStr
	 * @param actItem
	 * @return
	 * @throws Exception
	 */
	protected String[] sendQuickPay(String p_reqStr) throws Exception {
		String[] retStr = new String[] { "", "" };

		String submitURL = bankFront.getUrl("quickPay");

		WriteBankLogLn2("提交邦付宝地址: " + submitURL);

		WebRequest loginWebRequest = new WebRequest(submitURL);
		loginWebRequest.setConnectTimeout(10000);
		loginWebRequest.setRequestProperty("User-Agent", "API");

		WriteBankLogStep2(p_reqStr);

		byte[] tmpLoginBytes = p_reqStr.getBytes(getCharset());
		retStr = loginWebRequest.upload(tmpLoginBytes, getCharset());

		WriteBankLogStep3(retStr[1]);

		return retStr;
	}
	
	/**
	 * 获取对账单文件
	 * 
	 * @param p_reqURL
	 * @param p_reqXml
	 * @param actItem
	 * @return
	 * @throws Exception
	 */
	protected String[] getFileFromURL(String p_reqURL) throws Exception{
		String[] retStr = new String[]{"",""};
	
		WriteBankLogLn2("对账单文件获取地址: " + p_reqURL);
        
		WebRequest tmpWebRequest = new WebRequest(p_reqURL);
		tmpWebRequest.setConnectTimeout(60000);
		tmpWebRequest.setRequestProperty("connection", "Close");
		
		retStr = tmpWebRequest.upload(null, getCharset());
        
		return retStr;
	}

	/**
	 * 发邦付宝
	 * 
	 * @param map
	 * @param actItem
	 * @return
	 * @throws Exception
	 */
	protected String[] sendToBank(HashMap<String, String> map, ActSetItem actItem) throws Exception {
		Map<String, String> signMap = new HashMap<String, String>(); // 签名
		for (Map.Entry<String, String> entry : map.entrySet()) {
			String name = entry.getKey();
			String value = entry.getValue();
			if (!name.equals("signature") && (!value.equals(""))) {
				signMap.put(name, value);
			}
		}
		signMap = SortHelper.sortMapByName(signMap);
		String signStr = "";
		for (String key : signMap.keySet()) {
			signStr += "&" + key + "=" + signMap.get(key);
		}
		signStr = signStr.substring(1);
		StringBuilder tmpSb = new StringBuilder();
		String signature = SignVerifyHelper.signBySHARSA(signStr, actItem, tmpSb, getCharset());
		String[] retStr = new String[] { "", "" };
		if(signature == null){
			retStr[0] = "E9981";
			retStr[1] = "签名失败：" + tmpSb.toString();
			return retStr;
		}
		String sendStr = "";
		for (String key : signMap.keySet()) {
			sendStr += "&" + key + "=" + URLEncoder.encode(signMap.get(key), getCharset());
			// sendStr += "&" + key + "=" +signMap.get(key);
		}
		sendStr += "&" + "signature=" + URLEncoder.encode(signature, getCharset());
		sendStr = sendStr.substring(1);
		WriteBankLogLn2("签名的字符串" + signStr);
		WriteBankLogStep2(sendStr);

		// 发送给银行
		
		String tmpAddrLogin = bankFront.serverURL;
		WriteBankLogLn2("银行的地址" + tmpAddrLogin);
		WebRequest loginWebRequest = new WebRequest(tmpAddrLogin);
		loginWebRequest.setConnectTimeout(10000);
		loginWebRequest.setRequestProperty("User-Agent", "API");
		loginWebRequest.setRequestProperty("Cache-Control", "no-cache");
		loginWebRequest.setRequestProperty("Pragma", "no-cache");
		loginWebRequest.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
		byte[] tmpLoginBytes = sendStr.getBytes(getCharset());
		retStr = loginWebRequest.upload(tmpLoginBytes, getCharset());
		WriteBankLogStep3(retStr[1]);
		return retStr;
	}
	
	/**
	 *  获取待签名数据
	 * @param map
	 * @return
	 */
	protected String getSignStr(Map<String, String> map) {
		Map<String, String> signMap = new HashMap<String, String>();

		for (Map.Entry<String, String> entry : map.entrySet()) {
			String name = entry.getKey();
			String value = entry.getValue();

			if (!value.equals("") && !value.equals("merchantSign") && !value.equals("merchantCert")) {
				signMap.put(name, value);
			}
		}

		// Map排序
		signMap = SortHelper.sortMapByName(signMap);

		// Map转HTTP字符串
		String signStr = "";
		for (String key : signMap.keySet()) {
			signStr += "&" + key + "=" + signMap.get(key);
		}
		signStr = signStr.substring(1);
		
		return signStr;
	}
	
	/**
	 * 获取HTTP返回并转换为map
	 * 
	 * @param tmpStrRet
	 * @return
	 */
	protected Map<String, String> getRet(String tmpStrRet) {
		Map<String, String> map = new HashMap<String, String>();

		String strRets[] = tmpStrRet.split("&");
		for (String strRet : strRets) {
			String[] keyValue = strRet.split("=", 2);
			map.put(keyValue[0], keyValue[1]);
		}

		return map;
	}
	
	/**
	 * 获取待验签数据
	 */
	protected String getVerifyStr(String tmpStrRet) {
		Map<String, String> map = new HashMap<String, String>();

		String strRets[] = tmpStrRet.split("&");
		for (String strRet : strRets) {
			String[] keyValue = strRet.split("=", 2);
			
			if (!keyValue[1].equals("") && !keyValue[0].equals("serverSign") 
					&& !keyValue[0].equals("serverCert")) {
				map.put(keyValue[0], keyValue[1]);
			}
		}
		
		Map<String, String> verifyMap = SortHelper.sortMapByName(map);
		String verifyStr = "";
		for (String key : verifyMap.keySet()) {
			verifyStr += "&" + key + "=" + verifyMap.get(key);
		}
		verifyStr = verifyStr.substring(1);
		
		return verifyStr;
	}
}
